<template>
  <div ref="iconSelectRef" :style="{ width: props.width }">
    <el-popover
      :visible="popoverVisible"
      :width="props.width"
      placement="bottom-end"
    >
      <template #reference>
        <div @click="togglePopover">
          <slot>
            <el-input
              v-model="selectedIcon"
              readonly
              :placeholder="$t('common.message.info.select_icon')"
              class="reference"
            >
              <template #prepend>
                <!-- 根据图标类型展示 -->
                <el-icon v-if="isElementIcon">
                  <component :is="selectedIcon.replace('el-icon-', '')" />
                </el-icon>
                <template v-else>
                  <svg-icon :icon-class="selectedIcon" />
                </template>
              </template>
              <!-- 清空按钮 -->
              <template #suffix>
                <el-icon
                  v-if="selectedIcon"
                  style="margin-right: 8px"
                  @click.stop="clearSelectedIcon"
                >
                  <CircleClose />
                </el-icon>

                <el-icon
                  :style="{
                    transform: popoverVisible ? 'rotate(180deg)' : 'rotate(0)',
                    transition: 'transform .5s',
                  }"
                >
                  <ArrowDown @click.stop="togglePopover" />
                </el-icon>
              </template>
              <!-- <template #append>
                <el-button @click="showTables">点击选择</el-button>
              </template> -->
            </el-input>
          </slot>
        </div>
      </template>

      <!-- 图标选择弹窗 -->
      <div ref="popoverContentRef">
        <el-input
          v-model="filterText"
          :placeholder="$t('common.message.info.search_icon')"
          clearable
          @input="filterIcons"
        />
        <el-tabs v-model="activeTab" @tab-click="handleTabClick">
          <el-tab-pane label="SVG" name="svg" v-if="!onlyEL">
            <el-scrollbar height="300px">
              <ul class="icon-grid">
                <li
                  v-for="icon in filteredSvgIcons"
                  :key="'svg-' + icon"
                  class="icon-grid-item"
                  @click="selectIcon(icon)"
                >
                  <el-tooltip :content="icon" placement="bottom" effect="light">
                    <svg-icon :icon-class="icon" />
                  </el-tooltip>
                </li>
              </ul>
            </el-scrollbar>
          </el-tab-pane>
          <el-tab-pane label="Element" name="element">
            <el-scrollbar height="300px">
              <ul class="icon-grid">
                <li
                  v-for="icon in filteredElementIcons"
                  :key="icon"
                  class="icon-grid-item"
                  @click="selectIcon(icon)"
                >
                  <el-icon>
                    <component :is="icon" />
                  </el-icon>
                </li>
              </ul>
            </el-scrollbar>
          </el-tab-pane>
        </el-tabs>
      </div>
    </el-popover>
  </div>
</template>

<script setup>
import { smartTranslate as $t } from '@/lang';
import { onClickOutside } from '@vueuse/core';
import * as ElementPlusIconsVue from '@element-plus/icons-vue';

const props = defineProps({
  modelValue: {
    type: String,
    default: '',
  },
  width: {
    type: String,
    default: '600px',
  },
  onlyEL: {
    type: Boolean,
    default: false,
  },
});

const emit = defineEmits(['update:modelValue']);
const iconSelectRef = ref();
const popoverContentRef = ref();
const popoverVisible = ref(false);
const activeTab = ref('svg');

const svgIcons = ref([]);
const elementIcons = ref(Object.keys(ElementPlusIconsVue));
const selectedIcon = ref(props.modelValue);

const filterText = ref('');
const filteredSvgIcons = ref([]);
const filteredElementIcons = ref(elementIcons.value);
const isElementIcon = computed(() => {
  return selectedIcon.value && selectedIcon.value.startsWith('el-icon');
});

function loadIcons() {
  const icons = import.meta.glob('../../../assets/icons/*.svg');
  for (const path in icons) {
    const iconName = path.replace(/.*\/(.*)\.svg$/, '$1');
    svgIcons.value.push(iconName);
  }
  filteredSvgIcons.value = svgIcons.value;
}

function handleTabClick(tabPane) {
  activeTab.value = tabPane.props.name;
  filterIcons();
}

function filterIcons() {
  if (activeTab.value === 'svg') {
    filteredSvgIcons.value = filterText.value
      ? svgIcons.value.filter((icon) =>
          icon.toLowerCase().includes(filterText.value.toLowerCase()),
        )
      : svgIcons.value;
  } else {
    filteredElementIcons.value = filterText.value
      ? elementIcons.value.filter((icon) =>
          icon.toLowerCase().includes(filterText.value.toLowerCase()),
        )
      : elementIcons.value;
  }
}

/**
 * element 只存储名称，不再添加前缀 'el-icon-'
 * svg 添加前缀 'svg-'
 * @param icon
 */
function selectIcon(icon) {
  // const iconName = activeTab.value === 'element' ? 'el-icon-' + icon : icon;
  const iconName = activeTab.value === 'svg' ? 'svg-' + icon : icon;
  selectedIcon.value = iconName;
  emit('update:modelValue', iconName);
  popoverVisible.value = false;
}

function togglePopover() {
  popoverVisible.value = !popoverVisible.value;
}

onClickOutside(iconSelectRef, () => (popoverVisible.value = false), {
  ignore: [popoverContentRef],
});

/**
 * 清空已选图标
 */
function clearSelectedIcon() {
  selectedIcon.value = '';
  emit('update:modelValue', '');
}

onMounted(() => {
  loadIcons();
  if (selectedIcon.value) {
    if (
      elementIcons.value.includes(selectedIcon.value.replace('el-icon-', ''))
    ) {
      activeTab.value = 'element';
    } else {
      activeTab.value = 'svg';
    }
  }
});

// 监听 modelValue 的变化
watch(
  () => props.modelValue,
  (newVal) => {
    selectedIcon.value = newVal;
  },
);
</script>

<style scoped lang="scss">
.reference :deep(.el-input__wrapper),
.reference :deep(.el-input__inner) {
  cursor: pointer;
}

.icon-grid {
  display: flex;
  flex-wrap: wrap;
}

.icon-grid-item {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px;
  margin: 4px;
  cursor: pointer;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  transition: all 0.3s;
}

.icon-grid-item:hover {
  border-color: #4080ff;
  transform: scale(1.2);
}
</style>
